package com.chuangjiangx.member.score.ddd.domain.repository;


import com.chuangjiangx.dddbase.Repository;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrScoreGiftRuleId;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrScoreStreamId;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrStoredStreamId;
import com.chuangjiangx.member.basic.ddd.domain.model.MemberId;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreStream;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreType;
import com.chuangjiangx.domain.shared.model.PayEntry;
import com.chuangjiangx.member.score.dao.mapper.InMbrScoreStreamMapper;
import com.chuangjiangx.member.score.dao.model.InMbrScoreStream;
import com.chuangjiangx.member.score.dao.model.InMbrScoreStreamExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

@Component
public class MbrScoreStreamRepository implements Repository<MbrScoreStream, MbrScoreStreamId> {

    @Autowired
    private InMbrScoreStreamMapper inMbrScoreStreamMapper;

    @Override
    public MbrScoreStream fromId(MbrScoreStreamId id) {
        InMbrScoreStream inMbrScoreStream = inMbrScoreStreamMapper.selectByPrimaryKey(id.getId());
        return wrap(inMbrScoreStream);
    }

    @Override
    public void update(MbrScoreStream mbrScoreStream) {
        InMbrScoreStream inMbrScoreStream = unbox(mbrScoreStream);
        inMbrScoreStream.setId(mbrScoreStream.getId().getId());
        inMbrScoreStream.setUpdateTime(new Date());
        inMbrScoreStreamMapper.updateByPrimaryKeySelective(inMbrScoreStream);
    }

    @Override
    public void save(MbrScoreStream mbrScoreStream) {
        InMbrScoreStream inMbrScoreStream = unbox(mbrScoreStream);
        inMbrScoreStream.setCreateTime(new Date());
        inMbrScoreStreamMapper.insertSelective(inMbrScoreStream);
        mbrScoreStream.setId(new MbrScoreStreamId(inMbrScoreStream.getId()));
    }


    /**
     * domain转成数据库对象
     */
    private InMbrScoreStream unbox(MbrScoreStream mbrScoreStream) {
        InMbrScoreStream in = new InMbrScoreStream();
        in.setMemberId(mbrScoreStream.getMemberId().getId());
        in.setScore(mbrScoreStream.getScore());
        in.setType(mbrScoreStream.getType().value);
        if (mbrScoreStream.getMbrStoredStreamId() != null) {
            in.setMbrStoredStreamId(mbrScoreStream.getMbrStoredStreamId().getId());
        }
        if (mbrScoreStream.getMbrScoreGiftRuleId() != null) {
            in.setMbrScoreGiftRuleId(mbrScoreStream.getMbrScoreGiftRuleId().getId());
        }
        if (mbrScoreStream.getOrderRefundNum() != null) {
            in.setOrderRefundNum(mbrScoreStream.getOrderRefundNum());
        }
        if (mbrScoreStream.getOrderPayNum() != null) {
            in.setOrderPayNum(mbrScoreStream.getOrderPayNum());
        }
        in.setPostTradingScore(mbrScoreStream.getPostTradingScore());

        in.setRemark(mbrScoreStream.getRemark());
        if(null != mbrScoreStream.getPayEntry()){
            in.setPayEntry(mbrScoreStream.getPayEntry().value);
        }
        in.setMerchantUserId(mbrScoreStream.getMerchantUserId());
        in.setStoreUserId(mbrScoreStream.getStoreUserId());
        in.setStoreId(mbrScoreStream.getStoreId());
        if(null != mbrScoreStream.getId()){
            in.setId(mbrScoreStream.getId().getId());
        }
        return in;
    }

    /**
     * 数据库对象转成domain对象
     */
    private MbrScoreStream wrap(InMbrScoreStream in) {

        if (in == null) {
            return null;
        } else {
            MbrScoreStream mbrScoreStream = new MbrScoreStream(
                    new MemberId(in.getMemberId()),
                    in.getScore(),
                    in.getType() == null ? null : MbrScoreType.getScoreType(in.getType()),
                    in.getMbrStoredStreamId() == null ? null : new MbrStoredStreamId(in.getMbrStoredStreamId()),
                    in.getMbrScoreGiftRuleId() == null ? null : new MbrScoreGiftRuleId(in.getMbrScoreGiftRuleId()),
                    in.getOrderRefundNum(),
                    in.getOrderPayNum(),
                    in.getPostTradingScore(),
                    in.getRemark(),
                    null == in.getPayEntry() ? null : PayEntry.getPayEntry(in.getPayEntry()),
                    in.getMerchantUserId(),
                    in.getStoreUserId(),
                    in.getStoreId()
            );
            if(null != in.getId()){
                mbrScoreStream.setId(new MbrScoreStreamId(in.getId()));
            }
            return mbrScoreStream;
        }
    }


    /**
     * 根据支付单号和积分类型查询积分明细
     *
     * @param payOrderNumber 支付单号
     * @param type           积分类型
     * @return 返回积分明细
     */
    public MbrScoreStream fromPayOrderNumberAndType(String payOrderNumber, MbrScoreType type) {
        InMbrScoreStreamExample example = new InMbrScoreStreamExample();
        example.createCriteria()
                .andOrderPayNumEqualTo(payOrderNumber)
                .andTypeEqualTo(type.value);
        List<InMbrScoreStream> inMbrScoreStreams = inMbrScoreStreamMapper.selectByExample(example);
        if (inMbrScoreStreams.isEmpty()) {
            return null;
        } else {
            InMbrScoreStream inMbrScoreStream = inMbrScoreStreams.get(0);
            return wrap(inMbrScoreStream);
        }
    }

    public MbrScoreStream fromOrderRefundNumAndType(String refundOrderNumber, MbrScoreType type) {
        InMbrScoreStreamExample example = new InMbrScoreStreamExample();
        example.createCriteria()
                .andOrderRefundNumEqualTo(refundOrderNumber)
                .andTypeEqualTo(type.value);
        List<InMbrScoreStream> inMbrScoreStreams = inMbrScoreStreamMapper.selectByExample(example);
        if (inMbrScoreStreams.isEmpty()) {
            return null;
        } else {
            InMbrScoreStream inMbrScoreStream = inMbrScoreStreams.get(0);
            return wrap(inMbrScoreStream);
        }
    }


    public MbrScoreStream fromMbrStoreStreamIdAndType(Long mbrStoredSteamId,MbrScoreType type) {
        InMbrScoreStreamExample example = new InMbrScoreStreamExample();
        example.createCriteria()
                .andMbrStoredStreamIdEqualTo(mbrStoredSteamId)
                .andTypeEqualTo(type.value);
        List<InMbrScoreStream> inMbrScoreStreams = inMbrScoreStreamMapper.selectByExample(example);
        if (inMbrScoreStreams.isEmpty()) {
            return null;
        } else {
            InMbrScoreStream inMbrScoreStream = inMbrScoreStreams.get(0);
            return wrap(inMbrScoreStream);
        }
    }


    public void deleteByMemberId(Long memberId) {
        InMbrScoreStreamExample example = new InMbrScoreStreamExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        List<InMbrScoreStream> list = inMbrScoreStreamMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            list.forEach(inMbrScoreStream -> {
                inMbrScoreStreamMapper.deleteByPrimaryKey(inMbrScoreStream.getId());
            });
        }
    }
}
